from enum import Enum
from typing import Any, List, Optional

from pydantic import BaseModel, Field, field_validator


class BaseSchema(BaseModel):
    reqId: int = Field(..., description="reqID 不能为空")


class ExecutorTypeEnum(Enum):
    """执行器类型枚举"""

    JAVA = 1
    PYTHON = 2


class DispatchJob(BaseModel):
    namespaceId: str = Field(..., description="namespaceId 不能为空")
    jobId: int = Field(..., description="jobId 不能为空")
    taskBatchId: int = Field(..., description="taskBatchId 不能为空")
    taskId: int = Field(..., description="taskId 不能为空")
    taskType: int = Field(..., description="taskType 不能为空")
    groupName: str = Field(..., description="group 不能为空")
    parallelNum: int = Field(..., description="parallelNum 不能为空")
    executorType: int = Field(..., description="executorType 不能为空")
    executorInfo: str = Field(..., description="executorInfo 不能为空")
    executorTimeout: int = Field(..., description="executorTimeout 不能为空")
    argsStr: Optional[str] = None
    shardingTotal: Optional[int] = None
    shardingIndex: Optional[int] = None
    workflowTaskBatchId: Optional[int] = None
    workflowNodeId: Optional[int] = None
    retryCount: Optional[int] = None
    retryScene: Optional[int] = Field(None, description="重试场景 auto、manual")
    isRetry: bool = Field(False, description="是否是重试流量")

    @field_validator("namespaceId", "groupName", "executorInfo", mode="before")
    def not_blank(cls, v, field):
        if not v or not v.strip():
            raise ValueError(f"{field.alias} 不能为空")
        return v


class StopJob(BaseModel):
    jobId: int = Field(..., description="jobId 不能为空")
    taskBatchId: int = Field(..., description="taskBatchId 不能为空")
    groupName: str = Field(..., description="group 不能为空")

    @field_validator("groupName", mode="before")
    def not_blank(cls, v, field):
        if not v or not v.strip():
            raise ValueError(f"{field.alias} 不能为空")
        return v


class DispatchJobRequest(BaseSchema):
    args: List[DispatchJob] = Field(..., description="args 不能为空")


class StopJobRequest(BaseSchema):
    args: List[StopJob] = Field(..., description="args 不能为空")


class StatusEnum(int, Enum):
    STATUS_FAILURE = 0
    STATUS_SUCCESS = 1


class ExecuteResult(BaseModel):
    status: StatusEnum
    result: object = None
    message: str

    @staticmethod
    def success(result: object = None):
        return ExecuteResult(
            status=StatusEnum.STATUS_SUCCESS,
            result=result,
            message="任务执行成功",
        )

    @staticmethod
    def failure(result: object = None):
        return ExecuteResult(
            status=StatusEnum.STATUS_FAILURE,
            result=result,
            message="任务执行失败",
        )


class NettyResult(BaseModel):
    status: StatusEnum = Field(..., description="status 不能为空")
    reqId: int = Field(..., description="reqId 不能为空")
    data: Any = Field({}, description="data 不能为空")
    message: str = Field("", description="data 不能为空")


class JobTaskTypeEnum(int, Enum):
    CLUSTER = 1
    BROADCAST = 2
    SHARDING = 3


class JobTaskBatchStatusEnum(int, Enum):
    WAITING = 1
    RUNNING = 2
    SUCCESS = 3
    FAIL = 4
    STOP = 5
    CANCEL = 6


class DispatchJobResult(BaseModel):
    jobId: int
    taskBatchId: int
    workflowTaskBatchId: Optional[int] = None
    workflowNodeId: Optional[int] = None
    taskId: int
    # 任务类型
    taskType: JobTaskTypeEnum
    groupName: str
    taskStatus: JobTaskBatchStatusEnum
    executeResult: ExecuteResult
    # 重试场景 auto、manual
    # TODO: 限定取值
    retryScene: Optional[int] = None
    # 是否是重试流量
    isRetry: bool = False

    @staticmethod
    def build(
        dispatchJobRequest: DispatchJobRequest,
        executeResult: ExecuteResult,
    ) -> "DispatchJobResult":
        args = dispatchJobRequest.args[0]
        return DispatchJobResult(
            jobId=args.jobId,
            taskBatchId=args.taskBatchId,
            workflowTaskBatchId=args.workflowTaskBatchId,
            workflowNodeId=args.workflowNodeId,
            taskId=args.taskId,
            taskType=args.taskType,
            groupName=args.groupName,
            taskStatus=(
                JobTaskBatchStatusEnum.SUCCESS
                if executeResult.status == StatusEnum.STATUS_SUCCESS
                else JobTaskBatchStatusEnum.FAIL
            ),
            executeResult=executeResult,
            retryScene=args.retryScene,
            isRetry=args.isRetry,
        )


class DispatchJobResultRequest(BaseModel):
    args: List[DispatchJobResult] = Field(..., description="args 不能为空")


class TaskLogFieldDTO(BaseModel):
    name: str
    value: Optional[str] = None


class LogTaskDTO(BaseModel):
    # 日志类型
    logType: str
    # 命名空间
    namespaceId: str
    # 组名称
    groupName: str
    # 上报时间
    realTime: int
    # 日志模型集合
    fieldList: List[TaskLogFieldDTO]


class JobLogTask(LogTaskDTO):
    # 任务信息id
    jobId: int
    # 任务实例id
    taskBatchId: int
    # 调度任务id
    taskId: int


class JobLogTaskDTO(BaseSchema):
    args: List[List[JobLogTask]]


def main():
    import json

    text = """{
    "reqId": 202,
    "args": [
        {
            "namespaceId": "764d604ec6fc45f68cd92514c40e9e1a",
            "jobId": 1,
            "taskBatchId": 55,
            "taskId": 52,
            "taskType": 1,
            "groupName": "snail_job_demo_group",
            "parallelNum": 1,
            "executorType": 1,
            "executorInfo": "testJobExecutor",
            "executorTimeout": 60,
            "taskName": "",
            "argsStr": "{\\\"jobParams\\\":\\\"\\\"}",
            "retryCount": 1,
            "retryScene": 1,
            "retry": true
        }
    ]
}"""
    data = json.loads(text)
    request = DispatchJobRequest(**data)
    print(request)

    text = """{
    "reqId": 258,
    "args": [
        {
            "jobId": 2,
            "taskBatchId": 102,
            "groupName": "snail_job_demo_group"
        }
    ]
}"""
    request = StopJobRequest(**json.loads(text))
    print(request)

    data = {
        "status": 1,
        "reqId": 1,
        "data": {},
    }

    result = NettyResult(**data)
    print(result)
    print(NettyResult(status=1, reqId=2))

    data = {
        "status": 1,
        "data": "PONG",
        "reqId": 1719387647863174200,
    }
    result = NettyResult(**data)
    print(result)

    text = """{
    "reqId": 5,
    "args": [
        [
            {
                "logType": "JOB",
                "namespaceId": "764d604ec6fc45f68cd92514c40e9e1a",
                "groupName": "group1",
                "jobId": 1,
                "taskBatchId": 235,
                "taskId": 168,
                "realTime": 1719976099703,
                "fieldList": [
                    {
                        "name": "time_stamp",
                        "value": "1719976099703"
                    },
                    {
                        "name": "level",
                        "value": "INFO"
                    },
                    {
                        "name": "thread",
                        "value": "snail-netty-server-2"
                    },
                    {
                        "name": "message",
                        "value": "批次:[235] 任务调度成功. "
                    },
                    {
                        "name": "location",
                        "value": "com.aizuda.snailjob.client.job.core.client.JobEndPoint.dispatchJob(JobEndPoint.java:68)"
                    },
                    {
                        "name": "throwable"
                    },
                    {
                        "name": "host",
                        "value": "192.168.0.111"
                    },
                    {
                        "name": "port",
                        "value": "1789"
                    }
                ]
            },
            {
                "logType": "JOB",
                "namespaceId": "764d604ec6fc45f68cd92514c40e9e1a",
                "groupName": "group1",
                "jobId": 1,
                "taskBatchId": 235,
                "taskId": 168,
                "realTime": 1719976099706,
                "fieldList": [
                    {
                        "name": "time_stamp",
                        "value": "1719976099706"
                    },
                    {
                        "name": "level",
                        "value": "INFO"
                    },
                    {
                        "name": "thread",
                        "value": "snail-job-job-235-1"
                    },
                    {
                        "name": "message",
                        "value": "任务执行成功 taskBatchId:[235] [{\\\"status\\\":1,\\\"result\\\":\\\"测试成功\\\",\\\"message\\\":\\\"任务执行成功\\\"}]"
                    },
                    {
                        "name": "location",
                        "value": "com.aizuda.snailjob.client.job.core.executor.JobExecutorFutureCallback.onSuccess(JobExecutorFutureCallback.java:80)"
                    },
                    {
                        "name": "throwable"
                    },
                    {
                        "name": "host",
                        "value": "192.168.0.111"
                    },
                    {
                        "name": "port",
                        "value": "1789"
                    }
                ]
            }
        ]
    ]
}"""
    job_log = JobLogTaskDTO(**json.loads(text))
    print(job_log)


if __name__ == "__main__":
    main()
